package lava.rt.linq.sql;


import java.lang.reflect.Field;


import java.util.*;
import java.util.Map.Entry;
import java.util.function.BiFunction;
import java.util.function.Supplier;


import lava.rt.linq.LinqExecption;
import lava.rt.linq.Entity;





public abstract  class  ViewTemplate<M extends Entity> {

	protected final SqlDataContext dataContext;
	
	protected final String tableName,columns;
	public final Class<M> entryClass;
	protected final Map<String,Field> entityFieldMap=new HashMap<>();
	
	protected final Supplier<M> entityBuilder;
	
	
	@SuppressWarnings("unchecked")
	protected ViewTemplate (SqlDataContext dataContext,String tableName,Supplier<M> entityBuilder) {
		this.dataContext=dataContext;
		this.tableName=tableName;
		this.entryClass=(Class<M>) entityBuilder.get().getClass();
		
		
		for(Entry<String, Field> ent :dataContext.getThisDeclaredFieldMap(entryClass).entrySet()){
			
			this.entityFieldMap.put(ent.getKey(), ent.getValue());
			
		}
		
		columns=String.join(",", this.entityFieldMap.keySet());
		
		entityFieldMap.forEach((k,v)->v.setAccessible(true));
		
		
		this.entityBuilder=entityBuilder;
	}
	
	
	
   public void selectCursoring(BiFunction<Integer,M,Integer> cursor,String where,String orderBy,Object...param) throws LinqExecption{
    	SelectCommand cmd=new SelectCommand(columns, tableName, where, orderBy);
        cmd.setParams(param);
        dataContext.cursoringEntities(entityBuilder,cmd,cursor);
        
	}
   
   

    
     
     
     public List<M> selectList(String where,String orderBy,int start,int limit,Object...param) throws LinqExecption{
    	 SelectCommand cmd=new SelectCommand(columns, tableName, where, orderBy);
    	 cmd.setParams(param);
    	 List<M> ret=dataContext.listEntities(entityBuilder,cmd,start,limit);
    	 return ret;
	}
    
    
    public PagingResult<M> selectPaging(String where,String orderBy,int start,int limit,Object...param) throws LinqExecption{
    	SelectCommand cmd=new SelectCommand( columns, tableName, where, orderBy);
    	cmd.setParams(param);
    	PagingResult<M> ret= dataContext.pagingEntities(entityBuilder,cmd,start,limit);
    	return ret;
	}
	
    
	

	
}
